package com.kkb.shopcenter.filter;

import com.kkb.shopcenter.common.exception.DefinitionException;
import com.kkb.shopcenter.common.utils.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.apache.dubbo.common.utils.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 自定义JWT认证过滤器
 * 该类继承自BasicAuthenticationFilter，在doFilterInternal方法中，
 * 从http头的Authorization 项读取token数据，然后用Jwts包提供的方法校验token的合法性。
 * 如果校验通过，就认为这是一个取得授权的合法请求
 * @author
 */

public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager){
        super(authenticationManager);
    }

    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String header = request.getHeader("Authorization");
        if(header == null || !header.startsWith("Bearer")){
            chain.doFilter(request,response);
            return;
        }

        UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);
        if(authenticationToken==null){
            chain.doFilter(request,response);
            return;
        }

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request,response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        if(StringUtils.isEmpty(token)){
            throw new DefinitionException("Token为空");
        }

        try{
            String    user = JwtUtil.parseToken(token).getSubject();
            if(user!=null){
                return  new UsernamePasswordAuthenticationToken(user,user,new ArrayList<>());
            }
        }catch (ExpiredJwtException e){
            throw  new DefinitionException("Token已过期");
        }catch (UnsupportedJwtException e){
            throw  new DefinitionException("Token格式错误");
        }catch (MalformedJwtException e){
            throw  new DefinitionException("Token未被正确构造");
        }catch (SignatureException e){
            throw  new DefinitionException("签名失败");
        }catch (IllegalArgumentException e){
            throw  new DefinitionException("非法参数异常");
        }
        return  null;
    }
}
